package com.mmall.concurrency.example.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class CountDownLatchExample1 {

    private final static int threadCount = 10;

    public static void main(String[] args) throws Exception {

        ExecutorService exec = Executors.newCachedThreadPool();

        /**
         * 利用它可以实现类似计数器的功能
         * 比如有一个任务A，它要等待其他任务执行完毕之后才能执行，
         * 此时就可以利用CountDownLatch来实现这种功能了。
         */

        //参数count为计数值
        final CountDownLatch countDownLatch = new CountDownLatch(threadCount);

        // 启动多个线程
        for (int i = 0; i < threadCount; i++) {
            final int threadNum = i;
            exec.execute(() -> {
                try {
                    test(threadNum);
                } catch (Exception e) {
                    log.error("exception", e);
                } finally {
                    // 将count值减1
                    countDownLatch.countDown();
                }
            });
        }
        // 调用await()方法的线程会被挂起，它会等待直到count值为0才继续执行
        // 如果注释掉此方法， log.info("finish"); 会立刻执行
        countDownLatch.await();
        log.info("finish");
        exec.shutdown();
    }

    private static void test(int threadNum) throws Exception {
        Thread.sleep(100);
        log.info("{}", threadNum);
        Thread.sleep(100);
    }
}
